"strict"
var AutoScaleSimulator = require("./AutoScaleLib/build/Release/AutoScaleLib").NodeSimulator;
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);

var LoadGenTypes = {
	"uniform": 0,
	"normal": 1,
	"exponential": 2,
	"keypath": 3
};

var ScaleRuleTypes = {
	"count": 0,
	"percent": 1
}

var ScaleRuleOps = {
	"less":1,
	"lessOrEqual":2,
	"greater":3,
	"greaterOrEqual":4
}

app.use(express.static([__dirname , "static"].join('/')));

io.on('connection', function(socket) {
	socket.on("start", function(data) {
		var step = 0;
		console.log(data);
		socket.multipler = data.speedMultiplier;
		var simulator = new AutoScaleSimulator(data.minInstance, data.maxInstance);
		simulator.setLoadGenerator(LoadGenTypes[data.loadGeneratorType], data.loadGeneratorOptions)
		if (data.scaleRules != undefined) {
			data.scaleRules.forEach(function(rule) {
				rule.by = ScaleRuleTypes[rule.scaleBy];
				rule.opcode = ScaleRuleOps[rule.scaleOp];
				simulator.addRule(rule);
			});
		}
		socket.loopId = setInterval(function() {
			var speedMultiplier = socket.multipler || 1;
			if (speedMultiplier > 100) speedMultiplier = 100;
			else if (speedMultiplier < 1) speedMultiplier = 1;
			var loadStatus = {
				"requestComing": 0,
				"requestComplete": 0
			};
			for (var i = 0; i < speedMultiplier; ++i) {
				if(simulator.isFinished())
				{
					clearInterval(socket.loopId);
					delete socket.loopId;
					socket.emit("finished");
					return;
				}
				simulator.oneStep();
				var oneLoad = simulator.getLoadStatus();
				loadStatus.requestComing += oneLoad.requestComing;
				loadStatus.requestComplete += oneLoad.requestComplete;
				++step;
			}
			loadStatus.stepCount = speedMultiplier;
			var serverStatus = simulator.getServerStatus();
			socket.emit("step", {
				"step":step,
				"serverStatus": serverStatus,
				"loadStatus": loadStatus
			});
		}, 1000);
	});
	
	socket.on('stop', function() {
		if (socket.loopId != undefined) {
			clearInterval(socket.loopId);
			delete socket.loopId;
		}
	});

	socket.on('disconnect', function() {
		if (socket.loopId != undefined) {
			clearInterval(socket.loopId);
		}
	});

	socket.on("speed", function(multipler) {
		if (typeof multipler == 'number')
			socket.multipler = multipler;
	});
});

var port = process.env.PORT || 80;
server.listen(port);